public class SimplifyRoads {
    /*
    public Graph<KrakEdge, KrakNode> simpleGraph(Graph<KrakEdge, KrakNode> g, double simplifyFactor) {
        Graph<KrakEdge, KrakNode> result = g.clone();
        List<KrakNode> startNodes = new ArrayList<KrakNode>();
        List<KrakNode> allNodes = new ArrayList<KrakNode>();
        List<KrakEdge> tempEdges = new ArrayList<KrakEdge>();
        LinkedList<KrakNode> tempListNodes = new LinkedList<KrakNode>();
        List<KrakEdge> finalEdges = new ArrayList<KrakEdge>();
        List<KrakNode> marked = new ArrayList<KrakNode>();
        allNodes = g.nodes;
        //List<KrakEdge> outEdges = new ArrayList<KrakEdge>();
        //List<KrakEdge> inEdges = new ArrayList<KrakEdge>();
        //for (KrakNode n : allNodes) {
        //outEdges = g.outGoingEdgesList(n);
        //inEdges = (List<KrakEdge>) g.incomingEdges(n);
        simplify(result, allNodes, tempEdges, tempListNodes, marked, startNodes, simplifyFactor);
        //}
        for(Node n : result.nodes) {
            Iterator itn = result.allEdges(n);
            if(itn!=null){
                while (itn.hasNext()){
                    KrakEdge temp = (KrakEdge) itn.next();
                    if(temp.getRoadStatus() != RoadStatus.SIMPLE)
                        result.edges.remove(temp);
                }
            }
        }
        //for(Node n : result.nodes) {
        //    Iterator itn = result.allEdges(n);
        //    while (itn.hasNext()){
        //        KrakEdge temp = (KrakEdge) itn.next();
        //        if(temp.getRoadStatus() == RoadStatus.SIMPLE)
        //
        //    }
        //}
        //System.out.println(result.edges.size());
        return result;

    }

    private void simplify(Graph<KrakEdge, KrakNode> result, List<KrakNode> allNodes, List<KrakEdge> tempEdges, LinkedList<KrakNode> tempListNodes, List<KrakNode> marked, List<KrakNode> startNodes, double simplifyFactor) {
        boolean doable = true;

        if (allNodes != null) {
            for (KrakNode n : allNodes) {
                if (!marked.contains(n)) {
                    //System.out.println(allNodes.size());
                    Iterator<KrakEdge> itk = graph.allEdges(n);
                    if (itk != null) {
                        while (itk.hasNext()) {
                            tempEdges.add(itk.next());
                            //System.out.println("added");
                        }
                        int p = neighbours(tempEdges);
                        //System.out.println("p=" + p);
                        if (p != 0) {
                            if (tempListNodes.size() != 0) {
                                if (p == 1) {
                                    //System.out.println(tempListNodes.size());
                                    tempListNodes.addFirst(n);

                                    //marked.add(n); De skal jo først addes når man ved hvilke nodes der er blevet brugt fra tempNodesList.
                                    //allNodes.remove(n);
                                    //simplify(g, allNodes, tempEdges, tempListNodes, marked, startNodes, simplifyFactor);
                                } else if (p == 2) {
                                    //System.out.println("not doable!");
                                    if (tempListNodes.size() > 1) {
                                        //System.out.println(4);
                                        //KrakNode startNode = tempListNodes.peekLast();
                                        //tempListNodes.removeLast();
                                        addSimpleEdge(result, allNodes, tempListNodes, marked, simplifyFactor);

                                        //    g.addSimpleRoad(new SimpleRoad(g.outGoingEdgesList(tempListNodes.get(tempListNodes.size() - 2)).get(0).getName(), tempListNodes.get(0), tempListNodes.get(tempListNodes.size() - 1), RoadType.MOTORVEJ, RoadStatus.SIMPLE));
                                    } else if (tempListNodes.size() == 1) {
                                        //add a normal node-to-node road without skipping any nodes.

                                        //System.out.println("nodelist = 1");
                                        KrakEdge temp;
                                        KrakNode m = tempListNodes.remove();
                                        Iterator<KrakEdge> it = graph.allEdges(n);
                                        while (it.hasNext()) {
                                            temp = it.next();
                                            //if (temp.getEndNode() == m && temp.getOtherEndNode(m) == n) {
                                            KrakEdge simple = temp;
                                            simple.setRoadStatus(RoadStatus.SIMPLE);
                                            //System.out.println(simple.getEnd().getX() + ", " + simple.getEnd().getY());
                                            //System.out.println(simple.getStart().getX() + ", " + simple.getStart().getY());
                                            simple.setOtherEndNode(m, n);
                                            //System.out.println(simple.getEnd().getX() + ", " + simple.getEnd().getY());
                                            //System.out.println(simple.getStart().getX() + ", " + simple.getStart().getY());
                                            result.addEdge(simple);
                                            //System.out.println("done");
                                            break;
                                        }
                                    }

                                    //tempListNodes.clear(); not necessary I think.
                                }
                            } else {
                                startNodes.add(n);
                                tempListNodes.addFirst(n);
                                //allNodes.remove(n);
                                //System.out.println("start added");
                            }
                        }
                    }
                }
                tempEdges.clear();
            }
        }
    }

    public double calcAngle(Line e, Line f) {
        double dotP = 0;
        double eVecX = e.getStart().getX() + e.getEnd().getX();
        double eVecY = e.getStart().getY() + e.getEnd().getY();

        double fVecX = f.getStart().getX() + f.getEnd().getX();
        double fVecY = f.getStart().getY() + f.getEnd().getY();

        dotP = eVecX * fVecX + eVecY * fVecY;
        return Math.cos(dotP);
    }

    private void addSimpleEdge(Graph<KrakEdge, KrakNode> g, List<KrakNode> allNodes, LinkedList<KrakNode> tempListNodes, List<KrakNode> marked, double simplifyFactor) {
        double simplifyVal = 0;
        //System.out.println(tempListNodes.size());
        KrakNode endNode = tempListNodes.peekFirst();
        KrakNode startNode = tempListNodes.peekLast();
        //tempListNodes.removeLast();
        //System.out.println(endNode.getY());
        //System.out.println(startNode.getY());
        for (KrakNode k : tempListNodes) {
            simplifyVal += k.getMapPoint().distPointToLine(new SimpleLine(startNode.getMapPoint(), endNode.getMapPoint()));
            //System.out.println(simplifyVal);
            if (simplifyVal > simplifyFactor) {
                //      System.out.println("det skrider ved if");
                tempListNodes.removeFirst();
                addSimpleEdge(g, allNodes, tempListNodes, marked, simplifyFactor);
                break;
            }
        }
        //System.out.println("det skrider ved else");
        KrakEdge temp;
        //KrakNode m = tempListNodes.removeLast();
        Iterator<KrakEdge> it = graph.allEdges(startNode);
        while (it.hasNext()) {
            //System.out.println("så langt her");
            //System.out.println(tempListNodes.size());
            temp = it.next();
            //System.out.println(temp.getStart().getX() + ", " + temp.getStart().getY());
            //System.out.println(temp.getEnd().getX() + ", " + temp.getEnd().getY());
            //System.out.println(m.getMapPoint().getX() + ", " + m.getMapPoint().getY());
            //for (KrakNode m : tempListNodes) {
            //  System.out.println("1 more");
            // if (temp.getStart().equals(m.getMapPoint()) || temp.getEnd().equals(m.getMapPoint())) {

            //System.out.println("nice");
            KrakEdge simple = temp;
            simple.setRoadStatus(RoadStatus.SIMPLE);
            simple.setOtherEndNode(startNode, tempListNodes.peekFirst());
            g.addEdge(simple);
            //System.out.println("edge added");
            break;
        }
        //}



        for (KrakNode a : tempListNodes) {
            //allNodes.remove(k);
            marked.add(a);

        }

    }

        public int neighbours(List<KrakEdge> tempEdges) {
        int count = 0;
        int neighbours = 0;
        //System.out.println(tempEdges.size());
        for (int i = 0; i < tempEdges.size() - 1; i++) {
            for (int j = i + 1; j < tempEdges.size(); j++) {
                if (!tempEdges.get(i).getStart().equals(tempEdges.get(j).getStart())) {
                    count++;
                }
                if (!tempEdges.get(i).getStart().equals(tempEdges.get(j).getEnd())) {
                    count++;
                }
                if (!tempEdges.get(i).getEnd().equals(tempEdges.get(j).getStart())) {
                    count++;
                }
                if (!tempEdges.get(i).getEnd().equals(tempEdges.get(j).getEnd())) {
                    count++;
                }
                if (count > 2) {
                    neighbours++;
                    //System.out.println("neigbours up");
                    if (neighbours > 2) {
                        return 2;
                    }
                }
            }
        }

        if (neighbours == 0) {
            return 0;
        }
        return 1;
    }
    //simpleGraph = simpleGraph(graph, f.getSimplifyLevel());
    */


    //private void removeTempNodes(ArrayList<KrakNode> tempNodes) {
        //For each temporaryNode
        //Make new edge with length of the nodes two outgoing edges.
        //Delete all nodes outgoing edges
        //Delete temporaryNode
    //}
}
